<?php


namespace App\Repositories\Admin\Question;


use App\Models\Question;
use App\Repositories\BaseRepository;
use Illuminate\Support\Facades\DB;

class QuestionRepository extends BaseRepository
{

    public function model()
    {
        // TODO: Implement model() method.
        return new Question();
    }

    public function pagination($where = [], $param = [])
    {
        if (isset($where['tag_id']) && $where['tag_id']) {
            $ids = DB::table('question_tag_relations')
                ->whereIn('tag_id', explode(',', $where['tag_id']))
                ->pluck('question_id');
            if ($ids) {
                $param['whereIn'][] = [
                    'id',
                    $ids
                ];
            }
            unset($where['tag_id']);
        }
        $param['field'] = ['id','type','pid','status','answer_num','correct_num'];
        return parent::pagination($where, $param); // TODO: Change the autogenerated stub
    }

    /**
     * 添加问题
     * @param $data
     * @return mixed
     * @throws \Exception
     */
    public function create($data, $tag_id_ary)
    {
        $insertData = $this->_pack_data($data);
        return DB::transaction(function () use ($insertData, $tag_id_ary) {
            /**
             * @var $new_question Question
             */
            $new_question = $this->model()->create($insertData);
            if ($new_question) {
                $new_question->tags()->sync($tag_id_ary);
            } else {
                return false;
            }
            return $new_question;
        });
    }
    public function patch(Question $question, $data,$tag_id_ary)
    {
        $updateData = $this->_pack_data($data);
        return DB::transaction(function () use ($question,$updateData, $tag_id_ary) {
            /**
             * @var $new_question Question
             */
            $update_success = $question->update($updateData);
            if ($update_success) {
                $question->tags()->sync($tag_id_ary);
            } else {
                return false;
            }
            return $question;
        });
    }
    private function _pack_data($data){
        $insertData = [];
        //类型
        $insertData['type'] = key_exists((int)$data['type'], Question::$mapType) ? $data['type'] : Question::TYPE_RADIO;
        //父id
        $insertData['pid'] = $data['pid'] ?? 0;
        //状态
        $insertData['status'] = $data['status'] ?? True;
        //内容
        $insertData['content'] = $data['content'] ?? "";
        //选项
        $options = [];
        $this->_pack_options($data, $options);
        $insertData['options'] = $options;
        //答案
        $keys = [];
        $this->_pack_keys($data, $keys, $options);
        $insertData['keys'] = $keys;
        //解析
        $insertData['analysis'] = $data['analysis'] ?? '';
        //排序
        $insertData['sort'] = $data['sort'] ?? Question::DEFAULT_SORT;
        return $insertData;
    }
    /**
     * 检查并装包选项
     * @param $data
     * @param $options
     * @throws \Exception
     */
    private function _pack_options($data, &$options)
    {
        if (isset($data['options']) && is_array($data['options'])) {
            foreach ($data['options'] as $k => $v) {
                if ($data['type'] == Question::TYPE_RADIO || $data['type'] == Question::TYPE_CHECKBOX) {
                    if (!isset($v['key']) || !isset($v['content']) || !isset($v['type'])) {
                        throw new \Exception('选项缺少重要参数', 422);
                    }
                    if (!key_exists((int)$v['type'], Question::$mapKeyType)) {
                        throw new \Exception('选项的选项类型不正确', 422);
                    }
                    $options[] = [
                        'key' => $v['key'],
                        'content' => $v['content'],
                        'type' => $v['type']
                    ];
                }
                if($data['type']==Question::TYPE_DECIDE){
                    if (!isset($v['key']) || !isset($v['content'])) {
                        throw new \Exception('选项缺少重要参数', 422);
                    }
                    $options[] = [
                        'key' => $v['key'],
                        'content' => $v['content']
                    ];
                }
            }
        } else {
            if ($data['type'] != Question::TYPE_MASTER) {
                throw new \Exception('选项不能为空且必须为数组', 422);
            }
        }
    }

    /**
     * 检查并装包答案
     * @param $data
     * @param $keys
     * @param $options
     * @throws \Exception
     */
    private function _pack_keys($data, &$keys, $options)
    {
        if (isset($data['keys']) && is_array($data['keys'])) {
            if ($data['type'] == Question::TYPE_RADIO || $data['type'] == Question::TYPE_CHECKBOX) {
                if (count($options) < count($data['keys'])) {
                    throw new \Exception('答案数量不能超过选项数量');
                }
            }
            if ($data['type'] == Question::TYPE_DECIDE) {
                if (!in_array($data['keys'][0], [1, 2])) {
                    throw new \Exception('判断题答案不正确');
                }
            }
            $keys = $data['keys'];
        } else {
            throw new \Exception("答案参数不正确");
        }
    }
}
